module mycpu_top(
    input clk,
    input reset,
    input [5:0] stall,

    output [31:0] inst_
    );

    wire [63:0] npc;
    wire [63:0] pc;
    wire [63:0] pc4;
    wire [31:0] inst;
    wire [31:0] if_id_o_inst;
    wire [63:0] if_id_o_inst_addr;
    wire id_write_to_mem;
    wire id_write_to_regfile;
    wire [4:0] id_reg_addr;
    wire [10:0] id_ALUControl;
    wire [63:0] id_branch_pc;
    wire [63:0] id_jump_pc;
    wire [1:0] id_pcsource;
    wire [63:0] id_sext_imm;
    wire id_aluimm;
    wire [63:0] id_data1;
    wire [63:0] id_data2;
    wire id_is_jump;
    wire [3:0] id_mem_control;
    wire id_mem_to_regfile;
    wire exe_write_to_mem;
    wire exe_write_to_regfile;
    wire [4:0] exe_reg_addr;
    wire [10:0] exe_ALUControl;
    wire [63:0] exe_sext_imm;
    wire exe_aluimm;
    wire [63:0] exe_data1;
    wire [63:0] exe_data2;
    wire [63:0] exe_jump_pc;
    wire exe_is_jump;
    wire [3:0] exe_mem_control;
    wire exe_mem_to_regfile;
    wire [63:0] exe_data;
    wire mem_write_to_mem;
    wire mem_write_to_regfile;
    wire [4:0] mem_reg_addr;
    wire [63:0] mem_data1;
    wire [63:0] mem_data2;
    wire [3:0] mem_mem_control;
    wire mem_mem_to_regfile;
    wire [63:0] mem_rdata;
    wire [63:0] mem_wdata;
    wire [63:0] wb_write_to_regfile;
    wire wb_mem_to_regfile;
    wire [4:0] wb_reg_addr;
    wire [63:0] wb_alu_data;
    wire [63:0] wb_mem_data;
    wire [63:0] wb_data_out;
    //wire [5:0] stall;
    wire [3:0] mem_select_signal;

    pc PC(.clk(clk), .reset(reset), .stall(stall), .i_inst_addr(npc), .o_inst_addr(pc));

    If IF(.i_inst_addr(pc), .pcsource(id_pcsource), .branch_pc(id_branch_pc), .jump_pc(id_jump_pc), .o_inst_addr(pc4));

    ram_r INST_RAM(.clk(clk), .addr(pc), .rdata(inst));

    if_id IF_ID(.clk(clk), .reset(reset), .stall(stall), .i_inst(inst), .i_inst_addr(pc4), .o_inst(if_id_o_inst), .o_inst_addr(if_id_o_inst_addr));

    decode DECODE(.clk(clk), .reset(reset), .inst(if_id_o_inst), .inst_addr(if_id_o_inst_addr), .wdata(wb_data_out), .waddr(wb_reg_addr), .exe_out_addr(exe_reg_addr), .exe_out(exe_data), .mem_in_addr(mem_reg_addr),
                  .mem_in(mem_wdata), .wb_write_to_regfile(wb_write_to_regfile), .write_to_mem(id_write_to_mem), .write_to_regfile(id_write_to_regfile), .reg_addr(id_reg_addr), .ALUControl(id_ALUControl), .branch_pc(id_branch_pc), .jump_pc(id_jump_pc), .pcsource(id_pcsource),
                  .sext_imm(id_sext_imm), .aluimm(id_aluimm), .data1(id_data1), .data2(id_data2), .is_jump(id_is_jump), .mem_control(id_mem_control), .mem_to_regfile(id_mem_to_regfile));
    
    id_exe ID_EXE(.clk(clk), .reset(reset), .stall(stall), .i_write_to_mem(id_write_to_mem), .i_write_to_regfile(id_write_to_regfile), .i_reg_addr(id_reg_addr), .i_ALUControl(id_ALUControl),
                  .i_sext_imm(id_sext_imm), .i_aluimm(id_aluimm), .i_data1(id_data1), .i_data2(id_data2), .i_jump_pc(id_jump_pc), .i_is_jump(id_is_jump), .i_mem_control(id_mem_control), .i_mem_to_regfile(id_mem_to_regfile),
                  .o_write_to_mem(exe_write_to_mem), .o_write_to_regfile(exe_write_to_regfile), .o_reg_addr(exe_reg_addr), .o_ALUControl(exe_ALUControl), .o_sext_imm(exe_sext_imm),
                  .o_aluimm(exe_aluimm), .o_data1(exe_data1), .o_data2(exe_data2), .o_jump_pc(exe_jump_pc), .o_is_jump(exe_is_jump), .o_mem_control(exe_mem_control), .o_mem_to_regfile(exe_mem_to_regfile));
    
    exe EXE(.sext_imm(exe_sext_imm), .aluimm(exe_aluimm), .data1(exe_data1), .data2(exe_data2), .is_jump(exe_is_jump), .jump_pc(exe_jump_pc), .ALUControl(exe_ALUControl), .data(exe_data));
    
    exe_mem EXE_MEM(.clk(clk), .reset(reset), .stall(stall), .i_write_to_mem(exe_write_to_mem), .i_write_to_regfile(exe_write_to_regfile), .i_reg_addr(exe_reg_addr), .i_data1(exe_data), .i_data2(exe_data2),
                    .i_mem_control(exe_mem_control), .i_mem_to_regfile(exe_mem_to_regfile), .o_write_to_mem(mem_write_to_mem), .o_write_to_regfile(mem_write_to_regfile), .o_reg_addr(mem_reg_addr),
                    .o_data1(mem_data1), .o_data2(mem_data2), .o_mem_control(mem_mem_control), .o_mem_to_regfile(mem_mem_to_regfile));
    
    ram_r_w DATA_RAM(.clk(clk), .reset(reset), .ena(mem_write_to_mem), .addr(mem_data1), .wdata(mem_wdata), .rdata(mem_rdata), .mem_select_signal(mem_select_signal));
    
    mem MEM(.mem_data_i(mem_rdata), .mem_wdata_i(mem_data2), .mem_addr(mem_data1), .mem_control(mem_mem_control), .mem_data_o(mem_wdata), .mem_select_signal(mem_select_signal));
    
    mem_wb MEM_WB(.clk(clk), .reset(reset), .stall(stall), .i_write_to_regfile(mem_write_to_regfile), .i_mem_to_regfile(mem_mem_to_regfile), .i_reg_addr(mem_reg_addr), .i_alu_data(mem_data1), .i_mem_data(mem_wdata),
                  .o_write_to_regfile(wb_write_to_regfile), .o_mem_to_regfile(wb_mem_to_regfile), .o_reg_addr(wb_reg_addr), .o_alu_data(wb_alu_data), .o_mem_data(wb_mem_data));
    
    wb WB(.mem_to_regfile(wb_mem_to_regfile), .alu_data(wb_alu_data), .mem_data(wb_mem_data), .data_out(wb_data_out));
endmodule
